package monster.comm.util;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Array;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


import org.apache.commons.beanutils.BeanUtilsBean;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
/**
 * 
 * @author jzk
 *  这个是bean的帮助类，主要用于单元测试
 */
public class BeanHelp {
	 /**
	   * 显示javaBean的的所有值
	   * @param jbName String
	   * @throws Exception
	   * 主要用途，如view层传递到service,或者service层传递到dao时候我们观察一个对象的值是否正确
	   */
	  public static void readValue(Object bean) {
	     try {
	    	 System.out.println("===读取"+bean.getClass()+"的属性值===============");
	    	 java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean.getClass());
		       java.beans.PropertyDescriptor[] pds = info.getPropertyDescriptors();
		       BeanWrapper wap=new BeanWrapperImpl(bean);
		    
		       for(int i=0;i<pds.length;i++){
		    	   String proName=pds[i].getName();
		    	   if(!"class".equals(proName)){
		    		   System.out.println(pds[i].getName() + "=" + wap.getPropertyValue(proName));
		    	   }
		    		   
		    	  
		       
	         
	       }
	     }
	     catch (Exception e) {
	     System.out.println(e.toString());
	   }

	  }
	  
	  /**
	   * 帮助我们做快速给一个bean赋值，我们在做单元测试的时候可以快速给一个javaBean对象赋值，这个自动给每一个
	   * bean赋初值1 
	   * @param bean
	   */
	  public static void writeBean(Object bean){
		 try{
			  java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean.getClass());
		       java.beans.PropertyDescriptor[] pds = info.getPropertyDescriptors();
		       BeanWrapper wap=new BeanWrapperImpl(bean);
		       for(int i=0;i<pds.length;i++){
		    	   String proName=pds[i].getName();
		    	   if(!"class".equals(proName)){
		    		   wap.setPropertyValue(proName,"1");
		    		   
		    	   }
		    		   
		    	  
		       }
		 }
		 catch (Exception e) {
		     System.out.println(e.toString());
		   }
		
		 
	  }
	  
     
     /**
      * 把request里面的值copy到javabean
      * @param dest
      * @param request
      * @throws IllegalAccessException
      * @throws InvocationTargetException
      */
     public static void copyValRquestToBean(Object dest,javax.servlet.http.HttpServletRequest request)throws IllegalAccessException,
     InvocationTargetException {
     	BeanUtilExp beanutil=new BeanUtilExp();
     	beanutil.copyValRquestToBean(dest, request);
     }
     /**
      * 把request里面的值copy个一个list对象
      * @Class destCls  list里面保存的对象，标准的javaBean的class
      * @param request
      * @param beanProName request的参数名和java Bean的属性都包含的名称
      * @return
      * @throws IllegalAccessException
      * @throws InvocationTargetException
      */
     public static List copyValRequestToList(Class destCls,javax.servlet.http.HttpServletRequest request,String beanProName)throws Exception {
    	 List list=copyValRequestToList(destCls,request, beanProName);
    	 return list; 
     }
     
     
	  public static void main(String args[]){
		 TestBean o=new TestBean();
		 writeBean(o);
		 readValue(o);
	  }
	  /**
	  
	       * 对一个bean进行深度复制，所有的属性节点全部会被复制
	  
	       *
	  
	       * @param source
	  
	       * @return
	  
	       * @throws InstantiationException
	  
	       * @throws IllegalAccessException
	  
	       * @throws InvocationTargetException
	  
	       * @see [类、类#方法、类#成员]
	  
	       */
	  
	      @SuppressWarnings({"unchecked", "rawtypes"})
	  
	      public static <T> T deepCopyBean(T source)
	  
	      {
	  
	          if (source == null)
	  
	          {
	  
	              return null;
	  
	          }
	  
	          try
	  
	          {
	  
	              if (source instanceof Collection)
	  
	              {
	  
	                  return (T)deepCopyCollection((Collection)source);
	 
	              }
	 
	              if (source.getClass().isArray())
	 
	              {
	 
	                  return (T)deepCopyArray(source);
	
	              }
	 
	              if (source instanceof Map)
	 
	              {
	
	                  return (T)deepCopyMap((Map)source);
	 
	              }
	
	              if (source instanceof Date)
	  
	              {
	 
	                  return (T)new Date(((Date)source).getTime());
	 
	              }
	
	              if (source instanceof Timestamp)
	
	              {
	 
	                  return (T)new Timestamp(((Timestamp)source).getTime());
	  
	              }
	 
	              // 基本类型直接返回原值
	 
	              if (source.getClass().isPrimitive() || source instanceof String || source instanceof Boolean
	
	                  || Number.class.isAssignableFrom(source.getClass()))
	 
	              {
	
	                  return source;
	 
	              }
	 
	              if (source instanceof StringBuilder)
	 
	              {
	 
	                  return (T)new StringBuilder(source.toString());
	 
	              }
	 
	              if (source instanceof StringBuffer)
	 
	              {
	 
	                  return (T)new StringBuffer(source.toString());
	  
	              }
	 
	              Object dest = source.getClass().newInstance();
	  
	              BeanUtilsBean bean = BeanUtilsBean.getInstance();
	 
	              PropertyDescriptor[] origDescriptors = bean.getPropertyUtils().getPropertyDescriptors(source);
	 
	              for (int i = 0; i < origDescriptors.length; i++)
	 
	              {
	  
	                  String name = origDescriptors[i].getName();
	 
	                  if ("class".equals(name))
	  
	                  {
	
	                      continue;
	 
	                  }
	
	                   
	 
	                  if (bean.getPropertyUtils().isReadable(source, name) && bean.getPropertyUtils().isWriteable(dest, name))
	 
	                  {
	  
	                      try
	 
	                      {
	  
	                          Object value = deepCopyBean(bean.getPropertyUtils().getSimpleProperty(source, name));
	  
	                          bean.getPropertyUtils().setSimpleProperty(dest, name, value);
	  
	                      }
	  
	                      catch (NoSuchMethodException e)
	  
	                      {
	  
	                      }
	  
	                  }
	  
	              }
	  
	              return (T)dest;
	  
	          }
	  
	          catch (Exception e)
	  
	          {
	  
	              throw new RuntimeException(e);
	  
	          }
	  
	      }
	  
	       
	  
	      @SuppressWarnings({"rawtypes", "unchecked"})
	  
	      private static Collection deepCopyCollection(Collection source)
	  
	          throws InstantiationException, IllegalAccessException
	  
	      {
	  
	          Collection dest = source.getClass().newInstance();
	  
	          for (Object o : source)
	  
	          {
	  
	              dest.add(deepCopyBean(o));
	  
	          }
	  
	          return dest;
	  
	      }
	  
	       
	  
	      private static Object deepCopyArray(Object source)
	  
	          throws InstantiationException, IllegalAccessException, ArrayIndexOutOfBoundsException, IllegalArgumentException
	  
	      {
	  
	          int length = Array.getLength(source);
	  
	          Object dest = Array.newInstance(source.getClass().getComponentType(), length);
	  
	          if (length == 0)
	  
	          {
	  
	              return dest;
	  
	          }
	  
	          for (int i = 0; i < length; i++)
	  
	          {
	  
	              Array.set(dest, i, deepCopyBean(Array.get(source, i)));
	  
	          }
	  
	          return dest;
	  
	      }
	  
	       
	  
	      @SuppressWarnings({"unchecked", "rawtypes"})
	  
	      private static Map deepCopyMap(Map source)
	  
	          throws InstantiationException, IllegalAccessException
	  
	      {
	  
	          Map dest = source.getClass().newInstance();
	  
	          for (Object o : source.entrySet())
	  
	          {
	  
	              Entry e = (Entry)o;
	  
	              dest.put(deepCopyBean(e.getKey()), deepCopyBean(e.getValue()));
	  
	          }
	  
	          return dest;
	  
	      }

	  
  
}




class TestBean{
	private Long id;
	private String name;
	private java.math.BigDecimal age;
	public java.math.BigDecimal getAge() {
		return age;
	}
	public void setAge(java.math.BigDecimal age) {
		this.age = age;
	}
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	
}
